#ifndef PCPS_PMC_HEADER
#define PCPS_PMC_HEADER

#include <src/pcps.h>
#include <src/input.h>
#include <src/hamiltonian.h>
#include <src/wavefunction.h>

namespace pcps { namespace pmc {

  // forward declaration of the Walker class
  template <class S, class PART, class REF> class Walker;

  //--------------------------------------------------------------------------------
  // pcps::pmc::driver_detail -- performs a projector monte carlo calculation
  //--------------------------------------------------------------------------------

  template <class S, class PART, class REF>
  void driver_detail(const pcps::Input & userinp, const pcps::Hamiltonian<S> & ham, const pcps::Wavefunction<S> & wfn);

  //--------------------------------------------------------------------------------
  // pcps::pmc::driver -- performs a projector monte carlo calculation
  //--------------------------------------------------------------------------------

  template <class S>
  void driver(const pcps::Input & userinp, const pcps::Hamiltonian<S> & ham, const pcps::Wavefunction<S> & wfn);

  //--------------------------------------------------------------------------------
  // pcps::pmc::split_and_combine -- splits and combines walkers to keep their
  //                                 weights close to one
  //--------------------------------------------------------------------------------

  template <class S, class PART, class REF, class GENERATOR>
  void split_and_combine(const pcps::Input & userinp,
                         const pcps::Hamiltonian<S> & ham,
                         const pcps::Wavefunction<S> & wfn,
                         const double n_active,
                         const bool fixed_phase,
                         pcps::Arena & arena,
                         GENERATOR & gen,
                         std::vector<boost::shared_ptr<pcps::pmc::Walker<S, PART, REF> > > & walkers,
                         std::list<boost::shared_ptr<pcps::pmc::Walker<S, PART, REF> > > & active_walkers,
                         std::list<boost::shared_ptr<pcps::pmc::Walker<S, PART, REF> > > & inactive_walkers);

} // end namespace pmc

} // end namespace pcps

#endif
